// Canvas.tsx
import React, { useState, useRef } from 'react';
import { useDrop } from 'react-dnd';
import { Responsive, WidthProvider } from 'react-grid-layout';
import { Resizable } from 'react-resizable';
import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css';
import type { CanvasWidget, WidgetMaterial } from './types';

// 包装响应式网格布局
const ResponsiveGridLayout = WidthProvider(Responsive);

// 画布组件
const Canvas: React.FC = () => {
  // 画布中所有组件
  const [widgets, setWidgets] = useState<CanvasWidget[]>([]);
  // 网格布局配置（12列，行高30px）
  const gridRef = useRef<HTMLDivElement>(null);

  // 定义放置目标（画布）
  const [, drop] = useDrop(() => ({
    accept: 'WIDGET',
    drop: (item: WidgetMaterial) => {
      // 拖放时生成新组件（默认放置在左上角）
      const newWidget: CanvasWidget = {
        ...item,
        layout: {
          i: `widget-${Date.now()}`, // 唯一ID
          x: 0,
          y: Infinity, // 放在最底部
          w: item.initialW,
          h: item.initialH,
        },
      };
      setWidgets((prev) => [...prev, newWidget]);
    },
  }));

  // 处理网格布局变化（位置/大小调整）
  const handleLayoutChange = (layout: ResponsiveLayout[]) => {
    setWidgets((prev) =>
      prev.map((widget) => {
        const updatedLayout = layout.find((item) => item.i === widget.layout.i);
        return updatedLayout ? { ...widget, layout: updatedLayout } : widget;
      })
    );
  };

  // 删除组件
  const handleDelete = (id: string) => {
    setWidgets((prev) => prev.filter((w) => w.layout.i !== id));
  };

  return (
    <div
      ref={(node) => {
        gridRef.current = node;
        drop(node); // 绑定放置目标到网格容器
      }}
      className="flex-1 border p-4 bg-gray-50"
    >
      <h3 className="font-bold mb-4">画布区域</h3>

      {/* 网格布局 */}
      <ResponsiveGridLayout
        layouts={{ lg: widgets.map((w) => w.layout) }} // 布局数据
        breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
        cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }} // 不同屏幕的列数
        rowHeight={30} // 行高（px）
        onLayoutChange={handleLayoutChange}
        isDraggable={true} // 允许在网格内拖拽调整位置
        isResizable={true} // 允许基础缩放（右下角）
        margin={[10, 10]} // 组件间距
        containerPadding={[20, 20]}
      >
        {/* 渲染画布中的组件 */}
        {widgets.map((widget) => (
          <div key={widget.layout.i} data-grid={widget.layout}>
            {/* 用 react-resizable 增强缩放能力（8方向） */}
            <Resizable
              width={(widget.layout.w * (gridRef.current?.clientWidth || 0)) / 12} // 计算宽度（适配网格）
              height={widget.layout.h * 30} // 行高*行数
              minConstraints={[(1 * (gridRef.current?.clientWidth || 0)) / 12, 2 * 30]} // 最小尺寸（1列宽，2行高）
              handles={['se', 'sw', 'ne', 'nw', 'e', 'w', 'n', 's']} // 8方向缩放
              onResize={(e, dir, ref) => {
                // 缩放时同步更新网格布局
                if (ref) {
                  const newW = Math.round((ref.offsetWidth / (gridRef.current?.clientWidth || 0)) * 12);
                  const newH = Math.round(ref.offsetHeight / 30);
                  setWidgets((prev) =>
                    prev.map((w) =>
                      w.layout.i === widget.layout.i
                        ? {
                            ...w,
                            layout: { ...w.layout, w: newW, h: newH },
                          }
                        : w
                    )
                  );
                }
              }}
            >
              <div className="h-full bg-white border p-3 shadow-sm">
                <div className="flex justify-between items-center mb-2">
                  <span className="font-medium">{widget.name}</span>
                  <button onClick={() => handleDelete(widget.layout.i)} className="text-red-500 hover:text-red-700">
                    ×
                  </button>
                </div>
                <p>类型：{widget.type}</p>
                <p>
                  尺寸：{widget.layout.w}列 × {widget.layout.h}行
                </p>
              </div>
            </Resizable>
          </div>
        ))}
      </ResponsiveGridLayout>
    </div>
  );
};

export default Canvas;
